import * as vscode from 'vscode';
import { CancellationToken, CompletionContext, ExtensionContext, Position, TextDocument } from 'vscode';
import { extractUrlApiKeyFromFile, extractAPIEndpointKeys } from './utils/apiKeyExtractor';
import { HybridActionParser } from './utils/hybridActionParser';
import { RegexActionParser } from './utils/regexActionParser';
const convertPath = require('@stdlib/utils-convert-path');

const fs = require('fs');
const os = require('os');

const platform = os.platform();
const isWindows = platform === 'win32';
const canReadFileTypes = ['ts','js','tsx','jsx'];
// Remove global variables, read configuration dynamically instead
let apiUrlNameList: string[] = [];

let xlogicActionList: string[] = [];

const languagesList = ['html', 'javascript', 'typescript', 'vue'];

/**
 * Get current innerActions from configuration
 */
function getCurrentInnerActions(): string[] {
  return (vscode.workspace.getConfiguration('xlogicTips').get('innerActions') as string).split(',');
}

/**
 * Get current actionParams from configuration
 */
function getCurrentActionParams(): string {
  return vscode.workspace.getConfiguration('xlogicTips').get('innerActionParams') as string;
}

/**
 * Filter out any action names containing 'baseActions'
 * This provides an extra layer of protection against baseActions being added to the action list
 */
function filterBaseActions(actions: string[]): string[] {
  return actions.filter(action => !action.includes('baseActions'));
}

/**
 * Get module action names using the new lightweight parser
 */
function getModuleActionName(fileName: string, storePath?: string, modelName?: string): string[] {
  let tsOrJsFilePath = fileName;
  if (storePath) {
    tsOrJsFilePath = convertPath(storePath + fileName, isWindows ? 'win32' : 'posix');
  }

  // Get current innerActions from configuration
  const currentInnerActions = getCurrentInnerActions();
  
  // Use synchronous regex parser for immediate results
  return RegexActionParser.getModuleActionNames(tsOrJsFilePath, modelName, currentInnerActions);
}

/**
 * Get root action names using the new lightweight parser
 */
function getRootActionName(tsOrJsFilePath: string): string[] {
  // Get current innerActions from configuration
  const currentInnerActions = getCurrentInnerActions();
  
  // Use synchronous regex parser for immediate results
  return RegexActionParser.getRootActionNames(tsOrJsFilePath, currentInnerActions);
}

/**
 * Get API URL names using the existing utility
 */
function getApiUrlNameList(absPath: string): string[] {
  return extractUrlApiKeyFromFile(absPath);
}

/**
 * Provide completion items for action commands
 */
function provideCompletionItemsForActionCommand(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
  const word = document.getText(document.getWordRangeAtPosition(position));
  const languageId = document.languageId;

  console.log("🚀 ~ file: extension.ts:65 ~ provideCompletionItems ~ word", word);

  let xLogicActionSnippet = new vscode.CompletionItem({
    label: 'xLogic',
    description: "xLogic生成的快捷方式",
  });

  let storeName = languageId === 'vue' ? 'store' : 'context';
  xLogicActionSnippet.kind = vscode.CompletionItemKind.Snippet;
  
  // Get current actionParams from configuration
  const currentActionParams = getCurrentActionParams();
  xLogicActionSnippet.insertText = new vscode.SnippetString(storeName + ".dispatch('${1|" + xlogicActionList.join(',') + "|}',{${2|" + currentActionParams + "|}:${3},${4|" + currentActionParams + "|}:${5}})");
  
  console.log("🚀 ~ file: extension.ts:72 ~ provideCompletionItems ~ xLogicActionSnippet", xLogicActionSnippet);
  
  return [xLogicActionSnippet];
}

/**
 * Provide completion items for action names
 */
function provideCompletionItemsForActionName(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
  const word = document.getText(document.getWordRangeAtPosition(position));
  const languageId = document.languageId;

  console.log("🚀 ~ file: extension.ts:65 ~ provideCompletionItems ~ word", word);

  let xLogicActionNameSnippet = new vscode.CompletionItem({
    label: 'xActionName',
    description: "显示完整的actionsName",
  });

  xLogicActionNameSnippet.kind = vscode.CompletionItemKind.Snippet;
  xLogicActionNameSnippet.insertText = new vscode.SnippetString("${1|" + xlogicActionList.join(',') + "|}");
  
  console.log("🚀 ~ file: extension.ts:72 ~ provideCompletionItems ~ xLogicActionNameSnippet", xLogicActionNameSnippet);
  
  return [xLogicActionNameSnippet];
}

/**
 * Provide completion items for API URL keys
 */
function provideCompletionItemsForApiUrlKey(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
  const word = document.getText(document.getWordRangeAtPosition(position));
  const languageId = document.languageId;

  console.log("🚀 ~ file: extension.ts:xx ~ provideCompletionItemsForApiUrlKey ~ word", word);

  let apiUrlKeySnippet = new vscode.CompletionItem({
    label: 'apiUrlKey',
    description: "显示完整的apiUrlNameList",
  });

  apiUrlKeySnippet.kind = vscode.CompletionItemKind.Snippet;
  apiUrlKeySnippet.insertText = new vscode.SnippetString("apiUrlKey:'${1|" + apiUrlNameList.join(',') + "|}',");

  console.log("🚀 ~ file: extension.ts:xx ~ provideCompletionItemsForApiUrlKey ~ apiUrlKeySnippet", apiUrlKeySnippet);

  return [apiUrlKeySnippet];
}

function resolveCompletionItem() {
  return null;
}

/**
 * Generate action map info using the lightweight parser
 */
function makeActionMapInfo(projectRootPath: string) {
  let storePath = convertPath(projectRootPath + '/src/store/modules/', isWindows ? 'win32' : 'posix');
  let storeIndexTs = convertPath(projectRootPath + '/src/store/index.ts', isWindows ? 'win32' : 'posix');
  let storeIndexJs = convertPath(projectRootPath + '/src/store/index.js', isWindows ? 'win32' : 'posix');
  let apiKeyFilePath = convertPath(projectRootPath + '/src/constant/sourceMap.ts', isWindows ? 'win32' : 'posix');
  
  fs.readdir(storePath, function(error: any, files: string[]) {
    if (error) {
      console.error("读取文件夹错误!!!!!");
      return;
    }

    // Check if store index.ts exists
    fs.access(storeIndexTs, fs.constants.F_OK, (error: any) => {
      if (error) { return; }
      let al = getRootActionName(storeIndexTs);
      // Filter out any actions containing 'baseActions' before pushing
      const filteredActions = filterBaseActions(al);
      xlogicActionList.push(...filteredActions);
    });

    // Check if store index.js exists
    fs.access(storeIndexJs, fs.constants.F_OK, (error: any) => {
      if (error) { return; }
      let al = getRootActionName(storeIndexJs);
      // Filter out any actions containing 'baseActions' before pushing
      const filteredActions = filterBaseActions(al);
      xlogicActionList.push(...filteredActions);
    });

    // Process module files
    files.forEach((fileName: string) => {
      let [modelName, fileType] = fileName.split('.');
      if (!canReadFileTypes.includes(fileType)) {
        return;
      }

      let al = getModuleActionName(fileName, storePath, modelName);
      // Filter out any actions containing 'baseActions' before pushing
      const filteredActions = filterBaseActions(al);
      xlogicActionList.push(...filteredActions);
    });
  });

   console.log("🚀 ~ makeActionMapInfoAsync ~ xlogicActionList:", xlogicActionList);

  // Get API URL names
  apiUrlNameList = getApiUrlNameList(apiKeyFilePath);
  console.log("🚀 ~ makeActionMapInfo ~ apiUrlNameMap:", apiUrlNameList);
}

/**
 * Async version of makeActionMapInfo using hybrid parser for better accuracy when possible
 */
async function makeActionMapInfoAsync(projectRootPath: string, context?: vscode.ExtensionContext) {
  let storePath = convertPath(projectRootPath + '/src/store/modules/', isWindows ? 'win32' : 'posix');
  let storeIndexTs = convertPath(projectRootPath + '/src/store/index.ts', isWindows ? 'win32' : 'posix');
  let storeIndexJs = convertPath(projectRootPath + '/src/store/index.js', isWindows ? 'win32' : 'posix');
  let apiKeyFilePath = convertPath(projectRootPath + '/src/constant/sourceMap.ts', isWindows ? 'win32' : 'posix');
  
  // Get current innerActions from configuration
  const currentInnerActions = getCurrentInnerActions();
  
  try {
    // Check if store index files exist and process them
    if (fs.existsSync(storeIndexTs)) {
      const al = await HybridActionParser.getRootActionNames(storeIndexTs, currentInnerActions, context);
      // Filter out any actions containing 'baseActions' before pushing
      // const filteredActions = filterBaseActions(al);
      xlogicActionList.push(...al);
    }
    
    if (fs.existsSync(storeIndexJs)) {
      const al = await HybridActionParser.getRootActionNames(storeIndexJs, currentInnerActions, context);
      // Filter out any actions containing 'baseActions' before pushing
      // const filteredActions = filterBaseActions(al);
      xlogicActionList.push(...al);
    }
    
    // Process module files
    if (fs.existsSync(storePath)) {
      const files = fs.readdirSync(storePath);
      
      for (const fileName of files) {
        const [modelName, fileType] = fileName.split('.');
        if (!canReadFileTypes.includes(fileType)) {
          continue;
        }

        const fullPath = convertPath(storePath + fileName, isWindows ? 'win32' : 'posix');
        const al = await HybridActionParser.getModuleActionNames(fullPath, modelName, currentInnerActions, context);
        // Filter out any actions containing 'baseActions' before pushing
        const filteredActions = filterBaseActions(al);
        xlogicActionList.push(...filteredActions);

      }
    }
    console.log("🚀 ~ makeActionMapInfoAsync ~ xlogicActionList:", xlogicActionList);
  } catch (error) {
    console.error('Error in async action map generation:', error);
    // Fallback to synchronous version
    makeActionMapInfo(projectRootPath);
  }

  // Get API URL names
  apiUrlNameList = getApiUrlNameList(apiKeyFilePath);
  console.log("🚀 ~ makeActionMapInfoAsync ~ apiUrlNameMap:", apiUrlNameList);
}

export function activate(context: ExtensionContext) {
  console.log('activate into ...............into------', vscode.workspace.workspaceFolders);
  
  // Reset action list
  xlogicActionList = [];
  
  if (!vscode.workspace.workspaceFolders) {
    return;
  }

  let projectRootPath: any = vscode.workspace.workspaceFolders[0]?.uri.path;

  if (isWindows) {
     projectRootPath = projectRootPath.slice(1);  // drop the first character
  }

  // Use async version for better accuracy when possible
  makeActionMapInfoAsync(projectRootPath, context).catch(() => {
    // Fallback to sync version if async fails
    makeActionMapInfo(projectRootPath);
  });

  // Register reload command
  let reloadActionCommad = vscode.commands.registerCommand('vscode-extension-xlogic-tips.actionreload', async () => {
    if (!vscode.workspace.workspaceFolders) {
      return;
    }
    
    xlogicActionList = [];
    // innerActions are now read dynamically from configuration

    let projectRootPath: any = vscode.workspace.workspaceFolders[0]?.uri.path;

    if (isWindows) {
      projectRootPath = projectRootPath.slice(1);  // drop the first character
    }

    // Use async version for reload
    try {
      await makeActionMapInfoAsync(projectRootPath, context);
    } catch (error) {
      makeActionMapInfo(projectRootPath);
    }
    
    vscode.window.showInformationMessage('重新加载成功');
  });

  // Register test command (unchanged)
  let testExtractKeysCommand = vscode.commands.registerCommand('vscode-extension-xlogic-tips.testExtractKeys', () => {
    if (!vscode.workspace.workspaceFolders) {
      vscode.window.showErrorMessage('请先打开一个工作区');
      return;
    }

    let projectRootPath: any = vscode.workspace.workspaceFolders[0]?.uri.path;

    if (isWindows) {
      projectRootPath = projectRootPath.slice(1);  // drop the first character
    }

    const testFilePath = convertPath(projectRootPath + '/test-with-functions.js', isWindows ? 'win32' : 'posix');
    const extractedKeys = extractAPIEndpointKeys(testFilePath);
    
    if (extractedKeys.length > 0) {
      vscode.window.showInformationMessage(`提取到 ${extractedKeys.length} 个有效的 API 端点键名（包含点号）: ${extractedKeys.slice(0, 3).join(', ')}${extractedKeys.length > 3 ? '...' : ''}`);
      console.log('提取到的所有有效 API 端点键名:', extractedKeys);
    } else {
      vscode.window.showWarningMessage('未能提取到任何有效的 API 端点键名');
    }
  });

  // Register subscriptions
  context.subscriptions.push(reloadActionCommad);
  context.subscriptions.push(testExtractKeysCommand);
  
  context.subscriptions.push(vscode.languages.registerCompletionItemProvider(languagesList, {
    provideCompletionItems: provideCompletionItemsForActionCommand,
    resolveCompletionItem
  }, 'x'));
  
  context.subscriptions.push(vscode.languages.registerCompletionItemProvider(languagesList, {
    provideCompletionItems: provideCompletionItemsForActionName,
    resolveCompletionItem
  }, 'x'));

  context.subscriptions.push(vscode.languages.registerCompletionItemProvider(languagesList, {
    provideCompletionItems: provideCompletionItemsForApiUrlKey,
    resolveCompletionItem
  }, 'apiUrlKey:'));
}

export function deactivate() {}